package jk.framework.spring.cloud.canary.loadbalancer.context;




import jk.framework.canary.core.po.RouteContext;
import jk.framework.spring.cloud.canary.loadbalancer.constant.CanarySpringCloudConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.RequestData;
import org.springframework.http.HttpHeaders;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;

import java.util.Map;
import java.util.Set;

/**
 * @author cuichao
 */
public class CanaryLoadBalanceRouteContext extends RouteContext<RequestData> {

   private final Logger logger = LoggerFactory.getLogger(CanaryLoadBalanceRouteContext.class);
   private final String header_meta_key_prefix = "header.";
   private final String attribute_meta_key_prefix = "attribute.";
   private final String cookie_meta_key_prefix = "cookie.";

    public static CanaryLoadBalanceRouteContext build(ServiceInstance instance, RequestData requestData){
        return new CanaryLoadBalanceRouteContext(instance,requestData);
    }

    private final ServiceInstance instance;

    private CanaryLoadBalanceRouteContext(ServiceInstance instance, RequestData requestData){
        this.instance = instance;
        this.condition = requestData;
        init();
    }


    private void init(){
        String currentVer = instance.getMetadata().get(CanarySpringCloudConstant.CURRENT_VERSION_KEY);
        super.setCurrentVersion(currentVer);
        String serviceId = instance.getServiceId();
        super.setRouteKey(serviceId);
        buildHeaderLabels();
        buildAttributeLabels();
        buildCookieLabels();
        if(logger.isDebugEnabled()){
            logger.debug("the routeContext condition class is"+this.condition.getClass());
            this.getLabelsKeys().forEach(v -> {
                logger.debug(String.format("the routeContext labels key is %s value is %s",v,this.getLabels(v)));
            });
        }
    }

    private void buildHeaderLabels(){
        HttpHeaders headers = this.condition.getHeaders();
        headers.keySet().forEach(v -> this.setLabels(header_meta_key_prefix+v,headers.get(v)));
    }

    private void buildAttributeLabels(){
        Map<String, Object> attributes = this.condition.getAttributes();
        if(attributes == null || attributes.isEmpty()){
            return;
        }
        attributes.keySet().forEach(v -> {
            Object attrVal = attributes.get(v);
            if(!(attrVal instanceof String)){
                return;
            }
            Set<String> value = StringUtils.commaDelimitedListToSet(attrVal.toString());
            this.setLabels(attribute_meta_key_prefix+v,value);
        });
    }


    private void buildCookieLabels(){
        MultiValueMap<String, String> cookies = this.condition.getCookies();
        if(cookies == null || cookies.isEmpty()){
            return;
        }
        cookies.keySet().forEach(v -> this.setLabels(cookie_meta_key_prefix+v, cookies.get(v)));
    }


}
